#include <string>
#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
#include "parser.h"
#include "split.h"

using namespace std;
using namespace stock_trade;

std::string Parser::baseDir = "../data/";

void Parser::Init(const string& baseDir)
{
    Parser::baseDir = baseDir;
}

vector<Transaction> Parser::ParseTransaction(const Stock& stock, const Date& date)
{
    //[{symbol:"sh600016",name:"民生银行",ticktime:"14:59:34",price:"6.590",volume:"134672",prev_price:"6.590",kind:"U"}
    //,{symbol:"sh600016",name:"民生银行",ticktime:"14:58:24",price:"6.600",volume:"151000",prev_price:"6.600",kind:"U"}
    string fileName = Parser::baseDir + "5times_400/" + stock.code + "/" + date.toString() + ".5times";
    vector<Transaction> vecTransactions;
    ifstream iFile(fileName.c_str());
    if (!iFile)
    {
        //cerr << "bad file " << fileName << endl;
        return vecTransactions;
    }
    vector<string> vecDate;
    split(fileName, "/", vecDate);
    string line;
    while(getline(iFile, line))
    {
        if (line[0] != '[')
            break;
        vector<string> vecString;
        split(line, "}", vecString);
        for (vector<string>::iterator i = vecString.begin();
                i != vecString.end();
                ++i)
        {
            if ((*i)[0] != '[' && (*i)[0] != ',')
                break;
            if ((*i).length() < 2 || (*i)[1] != '{')
                break;
            vector<string> strTransaction;
            split((*i).substr(2), ",", strTransaction);
            if (strTransaction.size() != 7)                 //
                break;
            vector<string> vecPart;
            Transaction transaction;
            for (int i = 0; i < 7; i++)
            {
                split(strTransaction[i], ":\"", vecPart);
                if (vecPart.size() != 2)
                    break;
                switch (i)
                {
                    case 0:
                        transaction.stock.code = vecPart[1].substr(0, vecPart[1].length() - 1);
                        break;
                    case 1:
                        transaction.stock.name = vecPart[1].substr(0, vecPart[1].length() - 1);
                        break;
                    case 2:
                        //cout << "time:" << vecPart[1].substr(0, vecPart[1].length() - 1) << endl;
                        transaction.time = vecPart[1].substr(0, vecPart[1].length() - 1);
                        break;
                    case 3:
                        transaction.price = atof((vecPart[1].substr(0, vecPart[1].length() - 1)).c_str());
                        break;
                    case 4:
                        transaction.number = atoi((vecPart[1].substr(0, vecPart[1].length() - 1)).c_str());
                        break;
                    case 5:
                        //preview price
                        //transaction.price = atof((vecPart[1].substr(0, vecPart[1].length() - 1)).c_str());
                        break;
                    case 6:
                        string strType = vecPart[1].substr(0, vecPart[1].length() - 1);
                        if (strType == "U")
                            transaction.type = UP;
                        else if (strType == "D")
                            transaction.type = DOWN;
                        else
                            transaction.type = NORMAL;
                        break;
                }
            }
            transaction.date = date;
            transaction.action = NONE;
            transaction.status = SUCCESS;
            vecTransactions.push_back(transaction);
        }
    }
    iFile.close();
    sort(vecTransactions.begin(), vecTransactions.end());
    return vecTransactions;
}

vector<Situation> Parser::ParseSituation(const Stock& stock, const Date& date)
{
    string fileName = Parser::baseDir + "buy_sell/" + stock.code + "/" + date.toString() + "/buy_sell";
    vector<Situation> vecSituation;
    ifstream iFile(fileName.c_str());
    if (!iFile)
    {
        //cerr << "bad file " << fileName << endl;
        return vecSituation;
    }
    string line;
    while(getline(iFile, line))
    {
        Situation situation;
        vector<string> vecAll;
        split(line, "\"", vecAll);
        if (vecAll.size() != 3)
            continue;
        situation.stock.code = vecAll[0].substr(11, 8);      //sh600016
        vector<string> vecCoreInformation;
        split(vecAll[1], ",", vecCoreInformation);
        if (vecCoreInformation.size() != 33)
            continue;
        situation.stock.name = vecCoreInformation[0];       //民生银行
        situation.time = vecCoreInformation[31];            //09:30:51
        situation.date = vecCoreInformation[30];            //2012-12-03
        for (int i = 29; i >=20 ; i-=2)                     //from large price to small
        {
            PriceQuantity pq;
            pq.price = atof(vecCoreInformation[i].c_str());
            pq.quantity = atof(vecCoreInformation[i - 1].c_str());
            situation.sell5.push_back(pq);
        }
        for (int i = 19; i >=10 ; i-=2)                     //from small price to large
        {
            PriceQuantity pq;
            pq.price = atof(vecCoreInformation[i].c_str());
            pq.quantity = atof(vecCoreInformation[i - 1].c_str());
            situation.buy5.push_back(pq);
        }
        situation.nowPrice = atof(vecCoreInformation[3].c_str());
        vecSituation.push_back(situation);
    }
    iFile.close();
    sort(vecSituation.begin(), vecSituation.end());
    return vecSituation;

}

vector<Situation> Parser::ParserLongTimeSituation(const Stock& stock, Date beginDate, const unsigned int beforeDay)
{
    vector<Situation> result;
    for (unsigned int i = 0; i < beforeDay; ++i)
    {
        vector<Situation> vecSituation = Parser::ParseSituation(stock, beginDate);        
        result.insert(result.end(), vecSituation.begin(), vecSituation.end());
        --beginDate;
    }
    sort(result.begin(), result.end());    
    return result;
}

vector<Transaction> Parser::ParserLongTimeTransaction(const Stock& stock, Date beginDate, const unsigned int beforeDay)
{
    vector<Transaction> result;
    //--beginDate;
    for (unsigned int i = 0; i < beforeDay; ++i)
    {
        vector<Transaction> vecTransactions = Parser::ParseTransaction(stock, beginDate);        
        result.insert(result.end(), vecTransactions.begin(), vecTransactions.end());
        --beginDate;
    }
    sort(result.begin(), result.end());    
    return result;
}

vector<Stock> Parser::readAllStock(const string& fileName)
{
    vector<Stock> vecStock;
    ifstream iFile(fileName.c_str());
    if (!iFile)
    {
        cerr << "read stock list from " << fileName << " failed !" << endl;
        return vecStock;
    }
    string line;
    while(getline(iFile, line))
    {
        if (line != "")
        {
            Stock stock(line, line);
            vecStock.push_back(stock);
        }
    }
    return vecStock;
}

